﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sexybeauty.Core.Inf.LogicEntity;
using System.Web.Security;
using Sexybeauty.Core.Inf.Entities;
using Sexybeauty.Core.ExServer.WorkPool;
using Sexybeauty.Core.ExServer.WorkPool.WorkHandle.Email;
using Sexybeauty.Core.Biz.Model;
using Sexybeauty.Framework.Common;
using System.Web;
using Sexybeauty.Core.Inf.LogicEntity.Cache;
using System.Text.RegularExpressions;
using Sexybeauty.Core.Inf.Entities.Table;

namespace Sexybeauty.Core.Biz
{
    public class UserBiz
    {
        #region Account
        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="entity"></param>
        /// <returns>注册失败返回null</returns>
        public static MemberEntity Register(MemberEntity member)
        {
            if (member != null && !String.IsNullOrEmpty(member.UserName) 
                    && UserNotExists(member.UserName))
            {
                var token = new AccountToken()
                {
                    ExpireDate = DateTime.Now.AddDays(7),
                    Token = Guid.NewGuid().ToString(),
                    UserName = member.UserName
                };
                member.Token = token.Token;
                member.Password = AesAlgorithm.Encrypt(member.Password);
                member = member.PostAdd();
                if (member != null)
                {
                    WorkPool.Append<AccountEmail>(WorkType.email_for_register,new AccountEmail()
                    {
                        Recipient = member.UserName,
                        Token = BuildFixToken(token)
                    });
                    return member;
                }
            }
            return null;
        }
        public static MemberDetailEntity UpdateMemberDetail(MemberDetailEntity memberDetailEntity)
        {
            using (Context ctx = new Context())
            {
                if (!String.IsNullOrEmpty(memberDetailEntity.UserName))
                {
                    MemberDetailEntity detialentity = null;
                    if (!ctx.MemberDetail.Any(c => c.UserName == memberDetailEntity.UserName))
                    {
                        memberDetailEntity.Fans = 0;
                        memberDetailEntity.Popularity = 0;
                        memberDetailEntity.Wealth = 0;
                        detialentity = memberDetailEntity.PostAdd();
                    }
                    else
                    {
                        var detail = ctx.MemberDetail.FirstOrDefault(c => c.UserName == memberDetailEntity.UserName);
                        if (detail != null)
                        {
                            detail.Alipay = String.IsNullOrEmpty(memberDetailEntity.Alipay) ? detail.Alipay : memberDetailEntity.Alipay;
                            detail.MainPhoto = String.IsNullOrEmpty(memberDetailEntity.MainPhoto) ? detail.MainPhoto : memberDetailEntity.MainPhoto;
                            detail.Tenpay = String.IsNullOrEmpty(memberDetailEntity.Tenpay) ? detail.Tenpay : memberDetailEntity.Tenpay;
                            detail.Words = String.IsNullOrEmpty(memberDetailEntity.Words) ? detail.Words : memberDetailEntity.Words;
                            detail.PostModify();
                            detialentity = new MemberDetailEntity(detail);

                        }
                    }
                    new MemberDetailCache().RefreshItem(memberDetailEntity.UserName);
                    return detialentity;
                }
            }
            return null;
        }
        private static string BuildFixToken(AccountToken token)
        {
            string str = token.ToJson();
            return AesAlgorithm.Encrypt(str);
        }
        public static MemberEntity CheckToken(string token)
        {
            if (String.IsNullOrEmpty(token))
            {
                return null;
            }
            token = AesAlgorithm.Decrypt(token);
            var accountToken = token.ToObject<AccountToken>();
            if (accountToken != null)
            {
                var user = new MemberEntity().Element(c => c.UserName == accountToken.UserName);
                if (user != null)
                {
                    if (user.Token == accountToken.Token
                        && accountToken.ExpireDate > DateTime.Now)
                    {
                        user.Token = Guid.NewGuid().ToString();
                        user.PostModify();
                        return user;
                    }
                }
            }
            return null;
        }
        public static MemberEntity Activation(string token)
        {
            var member = CheckToken(token);
            if (member != null)
            {
                member.IsActivate = true;
                if (member.PostModify() != null)
                {
                    return member;
                }
            }
            return null;
        }
        /// <summary>
        /// 登陆
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <param name="rememberMe"></param>
        /// <returns>登陆失败返回null</returns>
        public static MemberEntity Login(string userName, string password, bool rememberMe = false)
        {
            var user = new MemberEntity().Element(c => c.UserName == userName);
            if (user != null)
            {
                if (user.Password == Framework.Common.AesAlgorithm.Encrypt(password))
                {
                    FormsAuthentication.SetAuthCookie(userName, rememberMe);
                    return user;
                }
            }
            return null;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userName"></param>
        /// <returns>true:不存在 false:存在</returns>
        public static bool UserNotExists(string userName)
        {
            if (!String.IsNullOrEmpty(userName))
            {
                using (Context ctx = new Context())
                {
                    return !ctx.Member.Any(c => c.UserName == userName);
                }
            }
            return false;
        }
        /// <summary>
        /// 发重置密码邮件
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public static bool ResendPasswordReset(string userName)
        {
            var user = new MemberEntity().Element(c => c.UserName == userName);
            if (user != null)
            {
                var token = new AccountToken() { 
                    ExpireDate=DateTime.Now.AddDays(1),
                    Token=Guid.NewGuid().ToString(),
                    UserName=userName
                };
                user.Token = token.Token;
                if (user.PostModify() != null)
                {
                    WorkPool.Append<AccountEmail>(WorkType.email_for_resetpassword, new AccountEmail()
                    {
                        Recipient = user.UserName,
                        Token = BuildFixToken(token)
                    });
                }
                return true;
            }
            return false;
        }
        /// <summary>
        /// 更改密码
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public static MemberEntity ChangePassword(string userName, string password)
        {
            if (!String.IsNullOrEmpty(userName) &&
                !String.IsNullOrEmpty(password))
            {
                var user = new MemberEntity().Element(c => c.UserName == userName);
                if (user != null)
                {
                    user.Password = AesAlgorithm.Encrypt(password);
                    if (user.PostModify() != null)
                    {
                        return user;
                    }
                }
            }
            return null;
        }
        public static MemberEntity UpdateBaseInfo(string username, string words, string nickname, int gender, string birthday, int area, int role, string qq, string phone)
        {
            Member user = null;
            using (Context ctx = new Context())
            {
                user = ctx.Member.FirstOrDefault(c => c.UserName == username);
            }
            if (user != null)
            {
                user.NickName = nickname;
                user.Gender = gender == 1;
                user.Birthday = birthday.ToDateTime(DateTime.Parse("1990-01-01"));
                user.Area = area;
                user.Role = role;

                if (!String.IsNullOrEmpty(qq) && new Regex("^\\d{5,12}$").IsMatch(qq))
                {
                    user.QQ = qq;
                }
                if (!String.IsNullOrEmpty(phone) && new Regex("^\\d{11}$").IsMatch(phone))
                {
                    user.Phone = phone;
                }
                if (user.PostModify() > 0)
                {
                    new MemberCache().RefreshItem(username);

                    UpdateMemberDetail(new MemberDetailEntity()
                    {
                        Words = words,
                        UserName = user.UserName
                    });
                    return new MemberEntity(user);
                }

            }
            return null;
        }

       
        public static MemberEntity ReSendActiveMail(string username)
        {
            if(String.IsNullOrEmpty(username))
            {
                return null;
            }
            var user = new MemberEntity().Element(c => c.UserName == username);
            if (user != null)
            {
                var token = new AccountToken()
                {
                    ExpireDate = DateTime.Now.AddDays(7),
                    Token = Guid.NewGuid().ToString(),
                    UserName = user.UserName
                };
                user.Token = token.Token;
                user = user.PostModify();
                if (user != null)
                {
                    WorkPool.Append<AccountEmail>(WorkType.email_for_register, new AccountEmail()
                    {
                        Recipient = user.UserName,
                        Token = BuildFixToken(token)
                    });
                    return user;
                }
            }
            return null;
        }
        #endregion

        #region MemberDetail
        public static MemberEntity GetCurrentUser(bool isLoadDetail = false, bool isLoadAccount = false)
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                return GetUser(HttpContext.Current.User.Identity.Name, isLoadDetail, isLoadAccount);
            }
            return null;
        }
        public static MemberEntity GetUser(string username, bool isLoadDetail, bool isLoadAccount)
        {
            if (!String.IsNullOrEmpty(username))
            {
                var user = new MemberCache().GetItem(username);
                if (user != null)
                {
                    if (isLoadDetail)
                    {
                        user.LoadMemberDetail();
                    }
                    if (isLoadAccount)
                    {
                        user.LoadMemberAccount();
                    }
                    return user;
                }
            }
            return null;
        }
        #endregion

        #region Ablum
        public static List<MemberResourceEntity> GetResources(string username, CustomerFileLevel level, CustomerFileType type, int page, int pageSize)
        {
            if (String.IsNullOrEmpty(username))
            {
                return null;
            }
            using (Context ctx = new Context())
            {
                var list = (from c in ctx.MemberResource
                            where c.UserName == username && c.ResLevel == (int)level && c.ResType == (int)type
                            select c)
                            .OrderByDescending(c=>c.UploadDate)
                           .Skip(page * pageSize)
                           .Take(pageSize)
                           .ToList()
                           .Select(c => new MemberResourceEntity() { 
                            Comment=c.Comment,
                            Id=c.Id,
                            Path=c.Path,
                            ResGroup=c.ResGroup,
                            ResLevel= (CustomerFileLevel)c.ResLevel,
                            ResType= (CustomerFileType)c.ResType,
                            Snapshot=c.Snapshot,
                            UploadDate=c.UploadDate,
                            UserName=c.UserName
                           })
                           .ToList();
                return list;
            }
        }
        #endregion

        #region Frends
        public static List<FrendsEntity> GetFrends(string username,int page,int pageSize)
        {
            if (String.IsNullOrEmpty(username))
            {
                return null;
            }
            using (Context ctx = new Context()) 
            {
                var list = (from c in ctx.Frends
                            where c.Master == username
                            select c)
                           .OrderByDescending(c => c.RcdDate)
                           .Skip(page * pageSize)
                           .Take(pageSize)
                           .ToList()
                           .Select(c => new FrendsEntity() { 
                               Frend=c.Frend,
                               Id=c.Id,
                               Master=c.Master
                           })
                           .ToList();
                return list;
            }
        }
        public static List<MemberEntity> GetFrendsDetail(string username, int page, int pageSize)
        {
            if (String.IsNullOrEmpty(username))
            {
                return null;
            }
            List<FrendsEntity> data = null;
            using (Context ctx = new Context())
            {
                data = (from c in ctx.Frends
                            where c.Master == username
                            select c)
                           .OrderByDescending(c => c.RcdDate)
                           .Skip(page * pageSize)
                           .Take(pageSize)
                           .ToList()
                           .Select(c => new FrendsEntity()
                           {
                               Frend = c.Frend,
                               Id = c.Id,
                               Master = c.Master
                           })
                           .ToList();
            }
            List<MemberEntity> result = null;
            if (data != null)
            {
                result = new List<MemberEntity>();
                foreach (FrendsEntity item in data) { 
                    result.Add(GetUser(item.Frend,true,false));
                }
            }
            return result;
        }
        #endregion
    }
}
